home *** CD-ROM | disk | FTP | other *** search
/ Amiga Plus 2004 #11 / Amiga Plus CD - 2004 - No. 11.iso / AmiSoft / Misc / emu / fbzx.lha / fbzx / tape.c < prev    next >
C/C++ Source or Header  |  2004-01-04  |  23KB  |  748 lines

  1. #include "Z80.h"
  2. #include "computer.h"
  3. #include "emulator.h"
  4. #include "menus.h"
  5. #include "tape.h"
  6.  
  7. int elcontador=0;
  8. int eltstado=0;
  9. char elbit=0;
  10.  
  11. /* reads a tape file and updates the readed bit */
  12.  
  13. inline void tape_read(FILE *fichero, int tstados) {
  14.     if(ordenador.tape_file_type == TAP_TAP)
  15.         tape_read_tap(fichero,tstados);
  16.     else
  17.         tape_read_tzx(fichero,tstados);
  18.     
  19.     if(ordenador.pause)
  20.         return;
  21.     
  22. }
  23.  
  24. // manages TAP files in REAL_MODE
  25.  
  26. inline void tape_read_tap (FILE * fichero, int tstados) {
  27.  
  28.     static unsigned char value, value2;
  29.         
  30.     if (fichero == NULL)
  31.         return;
  32.  
  33.     if (!ordenador.pause) {
  34.         if (ordenador.tape_current_mode == TAP_TRASH) {        // initialize a new block                        
  35.             fread (&value, 1, 1, fichero);
  36.             fread (&value2, 1, 1, fichero);    // read block longitude
  37.             if (feof (fichero)) {
  38.                 rewind_tape(fichero,1);
  39.                 ordenador.tape_current_mode = TAP_TRASH;
  40.                 return;
  41.             }
  42.             ordenador.tape_byte_counter = ((unsigned int) value) + 256 * ((unsigned int) value2);
  43.             fread (&(ordenador.tape_byte), 1, 1, fichero);
  44.             ordenador.tape_bit = 0x80;
  45.             ordenador.tape_current_mode = TAP_GUIDE;
  46.             ordenador.tape_counter0 = 2168;
  47.             ordenador.tape_counter1 = 2168;
  48.             if (!(0x80 & ordenador.tape_byte))
  49.                 ordenador.tape_counter_rep = 3228;    // 4 seconds
  50.             else
  51.                 ordenador.tape_counter_rep = 1614;    // 2 seconds
  52.         }
  53.  
  54.         // if there's a pulse still being reproduce, just reproduce it
  55.  
  56.         if (ordenador.tape_counter0)     {
  57.             if (ordenador.tape_counter0 > tstados) {
  58.                 ordenador.tape_readed = 0;    // return 0
  59.                 ordenador.tape_counter0 -= tstados;    // decrement counter;
  60.                 return;
  61.             } else {
  62.                 tstados -= ordenador.tape_counter0;
  63.                 ordenador.tape_counter0 = 0;
  64.             }
  65.         }
  66.  
  67.         ordenador.tape_readed = 1;    // return 1
  68.         if (ordenador.tape_counter1) {
  69.             if (ordenador.tape_counter1 > tstados) {
  70.                 ordenador.tape_counter1 -= tstados;    // decrement counter;
  71.                 return;
  72.             } else {
  73.                 tstados -= ordenador.tape_counter1;
  74.                 ordenador.tape_counter1 = 0;
  75.                 ordenador.tape_readed = 0;    // return 0
  76.             }
  77.         }
  78.  
  79.         // pulse ended
  80.         
  81.         switch (ordenador.tape_current_mode) {
  82.         case TAP_GUIDE:    // guide tone
  83.             if (ordenador.tape_counter_rep) {    // still into guide tone
  84.                 ordenador.tape_counter_rep--;
  85.                 ordenador.tape_counter0 = 2168 - tstados;
  86.                 ordenador.tape_counter1 = 2168;    // new pulse
  87.                 return;
  88.             } else {    // guide tone ended. send sync tone
  89.                 ordenador.tape_counter0 = 667 - tstados;
  90.                 ordenador.tape_counter1 = 735;    // new pulse
  91.                 ordenador.tape_current_mode = TAP_DATA;    // data mode
  92.                 ordenador.tape_bit = 0x80;    // from bit0 to bit7
  93.                 return;
  94.             }
  95.             break;
  96.         case TAP_DATA:    // data
  97.             if (ordenador.tape_byte & ordenador.tape_bit) {    // next bit is 1
  98.                 ordenador.tape_counter0 = 1710 - tstados;
  99.                 ordenador.tape_counter1 = 1710;
  100.             } else {
  101.                 ordenador.tape_counter0 = 851 - tstados;
  102.                 ordenador.tape_counter1 = 852;
  103.             }
  104.             ordenador.tape_bit = ((ordenador.tape_bit >> 1) & 0x7F);    // from bit0 to bit7
  105.             if (!ordenador.tape_bit) {
  106.                 ordenador.tape_byte_counter--;
  107.                 if (!ordenador.tape_byte_counter) {    // ended the block
  108.                     ordenador.tape_current_mode = TAP_PAUSE;    // pause
  109.                     ordenador.tape_readed = 0;
  110.                     ordenador.tape_counter_rep = 3500000;    // 1 seconds
  111.                     return;
  112.                 }
  113.                 ordenador.tape_bit = 0x80;
  114.                 fread (&(ordenador.tape_byte), 1, 1, fichero);    // read next byte
  115.                 if (feof (fichero)) {
  116.                     rewind_tape(fichero,0);
  117.                     ordenador.tape_current_mode = TAP_STOP;    // stop tape
  118.                     return;
  119.                 }
  120.             }
  121.             break;
  122.         case TAP_PAUSE:    // pause
  123.             ordenador.tape_readed = 0;
  124.             if (ordenador.tape_counter_rep > tstados) {
  125.                 ordenador.tape_counter_rep -= tstados;
  126.             } else {
  127.                 ordenador.tape_counter_rep = 0;
  128.                 ordenador.tape_current_mode = TAP_TRASH;    // read new block
  129.             }
  130.             return;
  131.             break;
  132.         case TAP_STOP:
  133.             ordenador.tape_current_mode = TAP_TRASH;    // initialize
  134.             ordenador.pause = 1;    // pause it
  135.             break;
  136.         default:
  137.             break;
  138.         }
  139.     }
  140. }
  141.  
  142. // manages TZX files
  143.  
  144. inline void tape_read_tzx (FILE * fichero, int tstados) {
  145.  
  146.     static unsigned char value, value2,value3,value4,done;
  147.     static unsigned int bucle,bucle2;
  148.     
  149.     if ((fichero == NULL)||(ordenador.pause))
  150.         return;
  151.  
  152.     if (ordenador.tape_current_mode == TAP_TRASH) {        // initialize a new block
  153.         done = 0;
  154.         do {
  155.             fread(&value,1,1,fichero); // read block ID
  156.             //printf("ID: %X en %d\n",value,ftell(fichero));
  157.             if(feof(fichero))
  158.                 done = 1;
  159.             else
  160.                 switch(value) {
  161.                 case 0x10: // classic tape block
  162.                     done = 1;
  163.                     bucle = 0;
  164.                     ordenador.tape_current_bit = 0;
  165.                     ordenador.tape_bit0_level = 852;
  166.                     ordenador.tape_bit1_level = 1710;
  167.                     ordenador.tape_bits_at_end = 8;
  168.                     ordenador.tape_block_level = 2168;
  169.                     ordenador.tape_sync_level0 = 667;
  170.                     ordenador.tape_sync_level1 = 735;
  171.                     
  172.                     fread(&value2,1,1,fichero);
  173.                     fread(&value3,1,1,fichero); // pause length
  174.                     ordenador.tape_pause_at_end = ((unsigned int) value2) + 256 * ((unsigned int) value3);
  175.                     if(ordenador.tape_pause_at_end==0)
  176.                         ordenador.tape_pause_at_end=10; // to avoid problems
  177.                     ordenador.tape_pause_at_end *= 3500;
  178.                     fread (&value, 1, 1, fichero);
  179.                     
  180.                     fread (&value2, 1, 1, fichero);    // read block longitude
  181.                     if (feof (fichero)) {
  182.                         rewind_tape(fichero,1);
  183.                         ordenador.tape_current_bit = 0;
  184.                         ordenador.tape_current_mode = TAP_TRASH;                        
  185.                         for(bucle=0;bucle<10;bucle++)
  186.                             fread(&value3,1,1,fichero); // jump over the header
  187.                         return;
  188.                     }
  189.                     ordenador.tape_byte_counter = ((unsigned int) value) + 256 * ((unsigned int) value2);
  190.                     fread (&(ordenador.tape_byte), 1, 1, fichero);
  191.                     ordenador.tape_bit = 0x80;
  192.                     ordenador.tape_current_mode = TAP_GUIDE;
  193.                     ordenador.tape_counter0 = 2168;
  194.                     ordenador.tape_counter1 = 2168;
  195.                     if (!(0x80 & ordenador.tape_byte))
  196.                         ordenador.tape_counter_rep = 3228;    // 4 seconds
  197.                     else
  198.                         ordenador.tape_counter_rep = 1614;    // 2 seconds                    
  199.                     break;
  200.  
  201.                 case 0x11: // turbo tape block                    
  202.                     done = 1;
  203.                     bucle = 0;
  204.                     
  205.                     fread(&value2,1,1,fichero);
  206.                     fread(&value3,1,1,fichero);
  207.                     ordenador.tape_block_level = ((unsigned int) value2) + 256 * ((unsigned int) value3);
  208.                     fread(&value2,1,1,fichero);
  209.                     fread(&value3,1,1,fichero);
  210.                     ordenador.tape_sync_level0 = ((unsigned int) value2) + 256 * ((unsigned int) value3);
  211.                     fread(&value2,1,1,fichero);
  212.                     fread(&value3,1,1,fichero);
  213.                     ordenador.tape_sync_level1 = ((unsigned int) value2) + 256 * ((unsigned int) value3);
  214.                     fread(&value2,1,1,fichero);
  215.                     fread(&value3,1,1,fichero);
  216.                     ordenador.tape_bit0_level = ((unsigned int) value2) + 256 * ((unsigned int) value3);
  217.                     fread(&value2,1,1,fichero);
  218.                     fread(&value3,1,1,fichero);
  219.                     ordenador.tape_bit1_level = ((unsigned int) value2) + 256 * ((unsigned int) value3);
  220.                     fread(&value2,1,1,fichero);
  221.                     fread(&value3,1,1,fichero);
  222.                     ordenador.tape_counter_rep = ((unsigned int) value2) + 256 * ((unsigned int) value3);
  223.                     ordenador.tape_counter_rep /=2;
  224.                     fread(&value2,1,1,fichero);
  225.                     ordenador.tape_bits_at_end = value2;                    
  226.                     
  227.                     fread(&value2,1,1,fichero);
  228.                     fread(&value3,1,1,fichero); // pause length
  229.                     ordenador.tape_pause_at_end = ((unsigned int) value2) + 256 * ((unsigned int) value3);
  230.                     
  231.             
  232.                     if(ordenador.tape_pause_at_end==0)
  233.                         ordenador.tape_pause_at_end=10; // to avoid problems
  234.                     ordenador.tape_pause_at_end *= 3500;
  235.                     
  236.                     fread (&value, 1, 1, fichero);
  237.                     fread (&value2, 1, 1, fichero);
  238.                     fread (&value3, 1, 1, fichero);    // read block longitude
  239.                     ordenador.tape_byte_counter = ((unsigned int) value) + 256 * ((unsigned int) value2) + 65536* ((unsigned int) value3);
  240.                     
  241.                     if (feof (fichero)) {
  242.                         rewind_tape(fichero,1);
  243.                         ordenador.tape_current_bit = 0;
  244.                         ordenador.tape_current_mode = TAP_TRASH;
  245.                         return;
  246.                     }
  247.                     
  248.                     fread (&(ordenador.tape_byte), 1, 1, fichero);
  249.                     ordenador.tape_bit = 0x80;
  250.                     ordenador.tape_current_mode = TAP_GUIDE;
  251.                     ordenador.tape_counter0 = ordenador.tape_block_level;
  252.                     ordenador.tape_counter1 = ordenador.tape_block_level;
  253.                     ordenador.tape_current_bit = 0;
  254.                     break;
  255.                     
  256.                 case 0x12: // pure tone
  257.                     done = 1;
  258.                     fread(&value2,1,1,fichero);
  259.                     fread(&value3,1,1,fichero); // length of pulse in T-states
  260.                     ordenador.tape_block_level = ((unsigned int) value2) + 256 * ((unsigned int) value3);
  261.                     ordenador.tape_counter0 = ordenador.tape_block_level;
  262.                     ordenador.tape_counter1 = 0;
  263.                     fread(&value2,1,1,fichero);
  264.                     fread(&value3,1,1,fichero); // number of pulses
  265.                     ordenador.tape_counter_rep = ((unsigned int) value2) + 256 * ((unsigned int) value3);
  266.                     if(ordenador.tape_counter_rep == 0)
  267.                         done = 0;
  268.                     ordenador.tape_current_mode = TZX_PURE_TONE;
  269.                     break;
  270.  
  271.                 case 0x13: // multiple pulses
  272.                     done=1;
  273.                     fread(&value2,1,1,fichero); // number of pulses
  274.                     ordenador.tape_counter_rep = ((unsigned int) value2);
  275.                     if(ordenador.tape_counter_rep == 0)
  276.                         done = 0;
  277.                     else {
  278.                         fread(&value2,1,1,fichero);
  279.                         fread(&value3,1,1,fichero); // length of pulse in T-states
  280.                         ordenador.tape_counter0 = ((unsigned int) value2) + 256 * ((unsigned int) value3);
  281.                         ordenador.tape_counter1 = 0;
  282.                         ordenador.tape_current_mode = TZX_SEQ_PULSES;
  283.                     }
  284.                     break;
  285.                 
  286.                 case 0x14: // turbo tape block                    
  287.                     done = 1;
  288.                     bucle = 0;
  289.                     ordenador.tape_current_bit = 0;
  290.                     fread(&value2,1,1,fichero);
  291.                     fread(&value3,1,1,fichero);
  292.                     ordenador.tape_bit0_level = ((unsigned int) value2) + 256 * ((unsigned int) value3);
  293.                     fread(&value2,1,1,fichero);
  294.                     fread(&value3,1,1,fichero);
  295.                     ordenador.tape_bit1_level = ((unsigned int) value2) + 256 * ((unsigned int) value3);
  296.                     fread(&value2,1,1,fichero);
  297.                     ordenador.tape_bits_at_end = value2;
  298.                     fread(&value2,1,1,fichero);
  299.                     fread(&value3,1,1,fichero); // pause length
  300.                     ordenador.tape_pause_at_end = ((unsigned int) value2) + 256 * ((unsigned int) value3);
  301.                     /*if(ordenador.tape_pause_at_end==0)
  302.                         ordenador.tape_pause_at_end=10;*/ // to avoid problems
  303.                     ordenador.tape_pause_at_end *= 3500;
  304.                     fread (&value, 1, 1, fichero);                    
  305.                     fread (&value2, 1, 1, fichero);
  306.                     fread (&value3,1,1,fichero);    // read block longitude
  307.                     if (feof (fichero)) {
  308.                         rewind_tape(fichero,1);
  309.                         ordenador.tape_current_bit = 0;
  310.                         ordenador.tape_current_mode = TAP_TRASH;                        
  311.                         return;
  312.                     }
  313.                     ordenador.tape_byte_counter = ((unsigned int) value) + 256 * ((unsigned int) value2) + 65536*((unsigned int)value3);                    
  314.                     ordenador.tape_bit = 0x80;
  315.                     fread (&(ordenador.tape_byte), 1, 1, fichero);    // read next byte
  316.                     if((ordenador.tape_byte_counter==1)&&(ordenador.tape_bits_at_end!=8)) { // last byte
  317.                         for(bucle=ordenador.tape_bits_at_end;bucle<8;bucle++) {
  318.                             ordenador.tape_byte=((ordenador.tape_byte>>1)&0x7F);
  319.                             ordenador.tape_bit = ((ordenador.tape_bit>>1)&0x7F);
  320.                         }
  321.                     }
  322.                     ordenador.tape_current_mode = TAP_DATA;
  323.                     ordenador.tape_counter0 = 0;
  324.                     ordenador.tape_counter1 = 0;
  325.                     ordenador.tape_counter_rep = 0;                    
  326.                     break;
  327.  
  328.                 case 0x20: // pause
  329.                     done = 1;
  330.                     fread(&value2,1,1,fichero);
  331.                     fread(&value3,1,1,fichero); // pause length
  332.                     ordenador.tape_counter_rep = ((unsigned int) value2) + 256 * ((unsigned int) value3);
  333.                     ordenador.tape_readed = 0;
  334.                     ordenador.tape_counter0 = 0;                
  335.                     ordenador.tape_counter1 = 0; // 1ms of inversed pulse                    
  336.                     if(ordenador.tape_counter_rep == 0) {
  337.                         ordenador.tape_current_mode = TAP_PAUSE2;    // initialize
  338.                         ordenador.tape_byte_counter = 31500;
  339.                         break;
  340.                     }
  341.                     ordenador.tape_counter_rep *= 3500;
  342.                     ordenador.tape_current_mode = TAP_PAUSE;                                    
  343.                     break;
  344.                     
  345.                 case 0x21: // group start
  346.                     fread(&value2,1,1,fichero);
  347.                     bucle2=(unsigned int) value2;
  348.                     for(bucle=0;bucle<bucle2;bucle++)
  349.                         fread(&value2,1,1,fichero);
  350.                     break;
  351.                     
  352.                 case 0x22: // group end
  353.                     break;
  354.                 
  355.                 case 0x24: // loop start
  356.                     fread(&value2,1,1,fichero);
  357.                     fread(&value3,1,1,fichero);
  358.                     ordenador.tape_loop_counter = ((unsigned int) value2) + 256 * ((unsigned int) value3);
  359.                     ordenador.tape_loop_pos = ftell(fichero);
  360.                     break;
  361.                 
  362.                 case 0x25: // loop end
  363.                     if(ordenador.tape_loop_counter) {
  364.                         ordenador.tape_loop_counter--;
  365.                         fseek(fichero,ordenador.tape_loop_pos,SEEK_SET);
  366.                     }
  367.                     break;
  368.                 
  369.                 case 0x2A: // pause if 48K
  370.                     if(ordenador.mode128k==0) {
  371.                         ordenador.pause = 1;
  372.                         return;
  373.                     }
  374.                     break;
  375.                     
  376.                 case 0x30: // text description
  377.                     fread(&value2,1,1,fichero); // length
  378.                     for(bucle=0;bucle<((unsigned int)value2);bucle++)
  379.                         fread(&value3,1,1,fichero);
  380.                     break;
  381.                     
  382.                 case 0x31: // show text
  383.                     fread(&value2,1,1,fichero);
  384.                     fread(&value2,1,1,fichero); // length
  385.                     for(bucle=0;bucle<((unsigned int)value2);bucle++)
  386.                         fread(&value3,1,1,fichero);
  387.                     break;
  388.                     
  389.                 case 0x32: // archive info
  390.                     fread(&value2,1,1,fichero);
  391.                     fread(&value3,1,1,fichero); // pause length
  392.                     bucle2 = ((unsigned int) value2) + 256 * ((unsigned int) value3);
  393.                     for(bucle=0;bucle<bucle2;bucle++)
  394.                         fread(&value3,1,1,fichero);
  395.                     break;
  396.                 
  397.                 case 0x33: // hardware info
  398.                     fread(&value2,1,1,fichero);                    
  399.                     bucle2 = ((unsigned int) value2) *3;
  400.                     for(bucle=0;bucle<bucle2;bucle++)
  401.                         fread(&value3,1,1,fichero);
  402.                     break;
  403.                     
  404.                 case 0x34: // emulation info                    
  405.                     for(bucle=0;bucle<8;bucle++)
  406.                         fread(&value3,1,1,fichero);
  407.                     break;
  408.                     
  409.                 case 0x35: // custon info                    
  410.                     for(bucle=0;bucle<10;bucle++)
  411.                         fread(&value3,1,1,fichero);
  412.                     fread(&value,1,1,fichero);
  413.                     fread(&value2,1,1,fichero);
  414.                     fread(&value3,1,1,fichero);
  415.                     fread(&value4,1,1,fichero);
  416.                     bucle2 = ((unsigned int) value) + 256 * ((unsigned int) value2) + 65536*((unsigned int) value3) + 16777216*((unsigned int) value4);
  417.                     for(bucle=0;bucle<bucle2;bucle++)
  418.                         fread(&value3,1,1,fichero);
  419.                     break;
  420.                     
  421.                 default: // not supported
  422.                     sprintf(ordenador.osd_text,"Unsuported TZX. Contact FBZX autor. %X",value);
  423.                     ordenador.osd_time=200;
  424.                     rewind_tape(fichero,1); // rewind and stop
  425.                     ordenador.tape_current_mode = TAP_TRASH;
  426.                     return;                    
  427.                     break;
  428.                 }
  429.         } while (!done);            
  430.     }
  431.  
  432.     if (feof (fichero)) {
  433.         rewind_tape(fichero,1);
  434.         ordenador.tape_current_bit = 0;
  435.         ordenador.tape_current_mode = TAP_TRASH;        
  436.         return;
  437.     }
  438.     
  439.     // if there's a pulse still being reproduce, just reproduce it
  440.  
  441.     if (ordenador.tape_counter0)     {
  442.         if (ordenador.tape_counter0 > tstados) {
  443.             ordenador.tape_readed = ordenador.tape_current_bit;    // return current
  444.             ordenador.tape_counter0 -= tstados;    // decrement counter;
  445.             return;
  446.         } else {
  447.             tstados -= ordenador.tape_counter0;
  448.             ordenador.tape_counter0 = 0;
  449.         }
  450.     }
  451.     
  452.     ordenador.tape_readed = 1 - ordenador.tape_current_bit;    // return oposite current
  453.     if (ordenador.tape_counter1) {        
  454.         if (ordenador.tape_counter1 > tstados) {
  455.             ordenador.tape_counter1 -= tstados;    // decrement counter;
  456.             return;
  457.         } else {
  458.             tstados -= ordenador.tape_counter1;
  459.             ordenador.tape_counter1 = 0;
  460.             ordenador.tape_readed = ordenador.tape_current_bit;    // return current
  461.         }
  462.     }
  463.  
  464.     // pulse ended
  465.  
  466.     switch (ordenador.tape_current_mode) {
  467.     case TAP_FINAL_BIT:
  468.         ordenador.tape_current_mode = TAP_TRASH;
  469.         break;
  470.     case TAP_GUIDE:    // guide tone
  471.         if (ordenador.tape_counter_rep) {    // still into guide tone
  472.             ordenador.tape_counter_rep--;
  473.             ordenador.tape_counter0 = ordenador.tape_block_level - tstados;
  474.             ordenador.tape_counter1 = ordenador.tape_block_level;    // new pulse
  475.             return;
  476.         } else {    // guide tone ended. send sync tone            
  477.             ordenador.tape_counter0 = ordenador.tape_sync_level0 - tstados;
  478.             ordenador.tape_counter1 = ordenador.tape_sync_level0;    // new pulse
  479.             ordenador.tape_current_mode = TAP_DATA;    // data mode
  480.             ordenador.tape_bit = 0x80;    // from bit0 to bit7
  481.             if((ordenador.tape_byte_counter==1)&&(ordenador.tape_bits_at_end!=8)) { // last byte
  482.                 for(bucle=ordenador.tape_bits_at_end;bucle<8;bucle++) {
  483.                     ordenador.tape_byte=((ordenador.tape_byte>>1)&0x7F);
  484.                     ordenador.tape_bit = ((ordenador.tape_bit>>1)&0x7F);
  485.                 }
  486.             }
  487.             return;
  488.         }
  489.         break;
  490.     case TAP_DATA:    // data
  491.         if (ordenador.tape_byte & ordenador.tape_bit) {    // next bit is 1
  492.             ordenador.tape_counter0 = ordenador.tape_bit1_level - tstados;
  493.             ordenador.tape_counter1 = ordenador.tape_bit1_level;
  494.         } else {
  495.             ordenador.tape_counter0 = ordenador.tape_bit0_level - tstados;
  496.             ordenador.tape_counter1 = ordenador.tape_bit0_level;
  497.         }
  498.         ordenador.tape_bit = ((ordenador.tape_bit >> 1) & 0x7F);    // from bit0 to bit7
  499.         if (!ordenador.tape_bit) {            
  500.             ordenador.tape_byte_counter--;
  501.             if (!ordenador.tape_byte_counter) {    // ended the block
  502.                 if(ordenador.tape_pause_at_end) {                    
  503.                     ordenador.tape_current_mode = TAP_PAUSE3;    // pause                    
  504.                     ordenador.tape_counter_rep = ordenador.tape_pause_at_end;
  505.                 } else
  506.                     ordenador.tape_current_mode = TAP_FINAL_BIT;                    
  507.                 return;
  508.             }
  509.             ordenador.tape_bit = 0x80;
  510.             fread (&(ordenador.tape_byte), 1, 1, fichero);    // read next byte
  511.             if (feof (fichero)) {
  512.                 rewind_tape (fichero,0);
  513.                 ordenador.tape_current_bit = 0;                
  514.                 ordenador.tape_current_mode = TAP_STOP;    // stop tape
  515.                 return;
  516.             }
  517.             if((ordenador.tape_byte_counter==1)&&(ordenador.tape_bits_at_end!=8)) { // last byte
  518.                 for(bucle=ordenador.tape_bits_at_end;bucle<8;bucle++) {
  519.                     ordenador.tape_byte=((ordenador.tape_byte>>1)&0x7F);
  520.                     ordenador.tape_bit = ((ordenador.tape_bit>>1)&0x7F);
  521.                 }
  522.             }
  523.         }
  524.         break;
  525.         
  526.     case TAP_PAUSE3: // one pulse of 1 ms for ending the bit
  527.         ordenador.tape_counter0 = 3500; // 1 ms
  528.         ordenador.tape_counter1 = 0;        
  529.         ordenador.tape_current_mode = TAP_PAUSE;
  530.         break;
  531.         
  532.     case TAP_PAUSE:    // pause
  533.         ordenador.tape_readed = 0;
  534.         ordenador.tape_current_bit = 0;
  535.         if (ordenador.tape_counter_rep > tstados) {
  536.             ordenador.tape_counter_rep -= tstados;
  537.         } else {
  538.             ordenador.tape_counter_rep = 0;
  539.             ordenador.tape_current_mode = TAP_TRASH;    // read new block
  540.         }
  541.         break;
  542.     case TAP_PAUSE2:    // pause and stop
  543.         ordenador.tape_readed = 0;
  544.         ordenador.tape_current_bit = 0;
  545.         if (ordenador.tape_counter_rep > tstados) {
  546.             ordenador.tape_counter_rep -= tstados;
  547.         } else {
  548.             ordenador.tape_counter_rep = 0;
  549.             ordenador.tape_current_mode = TAP_TRASH;    // read new block
  550.             ordenador.pause = 1;
  551.         }
  552.         break;
  553.     case TZX_PURE_TONE:
  554.         ordenador.tape_counter_rep--;
  555.         ordenador.tape_current_bit = 1 - ordenador.tape_current_bit; // invert current bit
  556.         if (ordenador.tape_counter_rep) {    // still into guide tone            
  557.             ordenador.tape_counter0 = ordenador.tape_block_level - tstados;
  558.             ordenador.tape_counter1 = 0; // new pulse            
  559.         } else
  560.             ordenador.tape_current_mode = TAP_TRASH;    // next ID
  561.         break;
  562.     case TZX_SEQ_PULSES:
  563.         ordenador.tape_current_bit = 1 - ordenador.tape_current_bit; // invert current bit
  564.         ordenador.tape_counter_rep--;
  565.         if(ordenador.tape_counter_rep) {
  566.             fread(&value2,1,1,fichero);
  567.             fread(&value3,1,1,fichero); // length of pulse in T-states
  568.             ordenador.tape_counter0 = ((unsigned int) value2) + 256 * ((unsigned int) value3);
  569.             ordenador.tape_counter1 = 0;
  570.         } else
  571.             ordenador.tape_current_mode = TAP_TRASH;    // next ID        
  572.         break;
  573.             
  574.     case TAP_STOP:
  575.         ordenador.tape_current_bit = 0;
  576.         ordenador.tape_current_mode = TAP_TRASH;    // initialize
  577.         ordenador.pause = 1;    // pause it
  578.         break;
  579.     default:
  580.         break;
  581.     }
  582. }
  583.  
  584. void rewind_tape(FILE *fichero,unsigned char pause) {
  585.  
  586.     int thebucle;
  587.     unsigned char value;
  588.     
  589.     rewind (ordenador.tap_file);
  590.     if(ordenador.tape_file_type==TAP_TZX)
  591.         for(thebucle=0;thebucle<10;thebucle++)
  592.             fread(&value,1,1,ordenador.tap_file); // jump over the header
  593.     ordenador.pause=pause;
  594. }
  595.  
  596. unsigned char file_empty(FILE *fichero) {
  597.     
  598.     long position,position2;
  599.     
  600.     position=ftell(fichero);
  601.     fseek(fichero,0,SEEK_END); // set the pointer at end
  602.     position2=ftell(fichero);
  603.     fseek(fichero,position,SEEK_SET); // return the pointer to the original place
  604.     if(position2==0)
  605.         return 1; // empty file
  606.     else
  607.         return 0;    
  608. }
  609.  
  610. void save_file(FILE *fichero) {
  611.  
  612.     long position;
  613.     unsigned char xor,salir;
  614.     byte dato;
  615.     int longitud;
  616.             
  617.     position=ftell(fichero); // store current position
  618.     fseek(fichero,0,SEEK_END); // put position at end
  619.     xor=0;
  620.     
  621.     longitud=(int)(procesador.DE.W);
  622.     longitud+=2;
  623.     
  624.     dato=(byte)(longitud%256);
  625.     fprintf(fichero,"%c",dato);
  626.     dato=(byte)(longitud/256);
  627.     fprintf(fichero,"%c",dato); // file length
  628.  
  629.     fprintf(fichero,"%c",procesador.AF.B.h); // flag
  630.  
  631.     xor^=procesador.AF.B.h;
  632.  
  633.     salir = 0;
  634.     do {
  635.         if (procesador.DE.W == 0)
  636.             salir = 2;
  637.         if (!salir) {
  638.             dato=RdZ80(procesador.IX.W); // read data
  639.             fprintf(fichero,"%c",dato);
  640.             xor^=dato;
  641.             procesador.IX.W++;            
  642.             procesador.DE.W--;            
  643.         }
  644.     } while (!salir);
  645.     fprintf(fichero,"%c",xor);
  646.     procesador.IX.W++;
  647.     procesador.IX.W++;
  648.     fseek(fichero,position,SEEK_SET); // put position at end
  649.     
  650.     if(ordenador.tape_fast_load==1) //if we want fast load, we assume we want fast save too
  651.         ordenador.other_ret = 1;    // next instruction must be RET
  652.     
  653.     return;
  654. }
  655.  
  656. void fastload_block (FILE * fichero) {
  657.  
  658.     unsigned int longitud;
  659.     unsigned char value[65536], salir,empty,flag_found;    
  660.     unsigned int veces;
  661.  
  662.     ordenador.other_ret = 1;    // next instruction must be RET
  663.  
  664.     if (!(procesador.AF.B.l & C_FLAG)) { // if Carry=0, is VERIFY, so return OK
  665.         procesador.AF.B.l |= C_FLAG;     // verify OK
  666.         procesador.IX.W += procesador.DE.W;
  667.         procesador.DE.W = 0;
  668.         return;
  669.     }
  670.  
  671.     empty=file_empty(fichero);
  672.  
  673.     
  674.     if ((fichero == NULL)||(empty)) {
  675.         procesador.AF.B.l &= (~C_FLAG);    // Load error
  676.         procesador.IX.W += procesador.DE.W;
  677.         procesador.DE.W = 0;
  678.         if(empty)
  679.             sprintf (ordenador.osd_text, "Tape file empty");
  680.         else
  681.             sprintf (ordenador.osd_text, "No tape selected");
  682.         ordenador.osd_time = 100;
  683.         return;
  684.     }
  685.  
  686.     veces=0;
  687.  
  688.     flag_found=0;
  689.     do {
  690.         fread (value, 2, 1, fichero);    // read length of current block
  691.         if (feof (fichero))    {            // end of file?
  692.             veces++; // one more time rewinded
  693.             sprintf (ordenador.osd_text, "Tape rewind");            
  694.             ordenador.osd_time = 100;
  695.             rewind (fichero);    // again
  696.             fread (value, 2, 1, fichero);    // read length of current block
  697.         }
  698.         longitud = ((unsigned int) value[0]) + 256 * ((unsigned int) value[1]);
  699.         fread (value, 1, 1, fichero);    // read flag byte
  700.         longitud--;
  701.         if (value[0] != procesador.AF.B.h) { // different flag
  702.             fread (value, longitud, 1, fichero);    // jump to the next block
  703.             if (veces==3) { // tape rewinded three times? Block with that flag not found.
  704.                 sprintf(ordenador.osd_text,"Block with right flag not found");
  705.                 ordenador.osd_time = 100;
  706.                 procesador.AF.B.l &= (~C_FLAG);    // Load error
  707.                 return;
  708.             }
  709.         } else
  710.             flag_found = 1;
  711.     } while(flag_found == 0);
  712.  
  713.     salir = 0;
  714.     do {
  715.         if (longitud == 0)
  716.             salir = 1;
  717.         if (procesador.DE.W == 0)
  718.             salir = 2;
  719.         if (!salir) {
  720.             fread (value, 1, 1, fichero);    // read byte
  721.             WrZ80 (procesador.IX.W, (byte) value[0]);    // store the byte
  722.             procesador.IX.W++;            
  723.             procesador.DE.W--;
  724.             longitud--;
  725.         }
  726.     }
  727.     while (!salir);
  728.  
  729.     clean_screen ();
  730.  
  731.     if (salir == 1) { // system wants to load more bytes that the existent
  732.         procesador.AF.B.l &= (~C_FLAG);    // Load error
  733.         return;
  734.     }
  735.  
  736.     if ((salir == 2) && (longitud != 1)) { // there are more bytes to load
  737.         procesador.AF.B.l &= (~C_FLAG);    // Load error
  738.         if (longitud > 1)
  739.             fread (value, longitud, 1, fichero);    // jump to the next block
  740.         return;
  741.     }
  742.  
  743.     fread (value, 1, 1, fichero);    // jump over the checksum
  744.     procesador.AF.B.l |= C_FLAG;    // Load OK
  745.     return;
  746.  
  747. }
  748.